package com.hulman.oms.web;

import com.hulman.oms.bean.*;
import com.hulman.oms.service.*;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/scada")
@Slf4j
public class ScadaController
{
    @Autowired
    private UserService userService;
    @Autowired
    private FaultService faultService;
    @Autowired
    private PatrolService patrolService;
    @Autowired
    private RepairService repairService;
    @Autowired
    private WorkTaskService workTaskService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private MaintainTaskService maintainTaskService;
    @Autowired
    private ScadaReportService scadaReportService;

    @GetMapping("/{identifier}")
    public Result execute(@PathVariable("identifier") String identifier, @RequestParam Map<String, Object> params) throws SQLException
    {
        List<Map<String, Object>> data = scadaReportService.execute(identifier, params);
        return new Result(data, data.size());
    }

    /**
     * @return 人员统计（工单完成情况）
     */
    @Operation(summary = "人员统计（工单完成情况）")
    @GetMapping("/user-stat")
    public Result statUsers()
    {
        List<UserStat> statList = userService.statUsers();
        return new Result(statList, statList.size());
    }

    @Operation(summary = "当前在岗人数")
    @GetMapping("/on-duty-users-count")
    public Result findOnDutyUsersCount()
    {
        Integer data = userService.findOnDutyUsersCount();
        return new Result(data);
    }

    @Operation(summary = "今日巡检列表")
    @GetMapping("/today-patrols")
    public Result findTodayPatrols()
    {
        //List<Patrol> list = patrolService.findTodayPatrols();
        List<Patrol> list = patrolService.findLatestPatrols();
        return new Result(list, list.size());
    }

    @Operation(summary = "今日缺陷列表")
    @GetMapping("/today-faults")
    public Result findTodayFaults()
    {
        List<Fault> list = faultService.findTodayFaults();
        return new Result(list, list.size());
    }

    @Operation(summary = "今日维修列表")
    @GetMapping("/today-repairs")
    public Result findTodayRepairs()
    {
        List<Repair> list = repairService.findTodayRepairs();
        return new Result(list, list.size());
    }

    @Operation(summary = "最近缺陷记录")
    @GetMapping("/recent-faults")
    public Result findRecentFaults(Integer count)
    {
        List<Fault> list = faultService.findRecentFaults(count);
        return new Result(list, list.size());
    }

    @Operation(summary = "最近维修记录")
    @GetMapping("/recent-repairs")
    public Result findRecentRepairs(Integer count)
    {
        List<Repair> list = repairService.findRecentRepairs(count);
        return new Result(list, list.size());
    }

    @Operation(summary = "最近任务工单记录")
    @GetMapping("/recent-work-tasks")
    public Result findRecentWorkTasks(Integer count)
    {
        List<WorkTask> list = workTaskService.findRecentWorkTasks(count);
        return new Result(list, list.size());
    }

    @Operation(summary = "（隧道今日）发现缺陷数")
    @GetMapping("/today-faults-count")
    public Result findTodayFaultsCount(Integer tunnelId)
    {
        Integer data = faultService.findTodayFaultsCount(tunnelId);
        return new Result(data);
    }

    @Operation(summary = "（隧道今日）设备告警缺陷数")
    @GetMapping("/today-auto-faults-count")
    public Result findTodayAutoFaultsCount(Integer tunnelId)
    {
        Integer data = faultService.findTodayAutoFaultsCount(tunnelId);
        return new Result(data);
    }

    @Operation(summary = "（隧道今日）人工上报缺陷数")
    @GetMapping("/today-manual-faults-count")
    public Result findTodayManualFaultsCount(Integer tunnelId)
    {
        Integer data = faultService.findTodayManualFaultsCount(tunnelId);
        return new Result(data);
    }

    @Operation(summary = "（隧道今日）完成检修次数")
    @GetMapping("/today-completed-repairs-count")
    public Result findTodayCompletedRepairsCount(Integer tunnelId)
    {
        Integer data = repairService.findTodayCompletedRepairsCount(tunnelId);
        return new Result(data);
    }

    @Operation(summary = "今日缺陷总数")
    @GetMapping("/today-faults-total-count")
    public Result findTodayFaultsTotalCount()
    {
        Integer data = faultService.findTodayFaultsTotalCount();
        return new Result(data);
    }

    @Operation(summary = "今日维修总数")
    @GetMapping("/today-repairs-total-count")
    public Result findTodayRepairsTotalCount()
    {
        Integer data = repairService.findTodayRepairsTotalCount();
        return new Result(data);
    }

    @Operation(summary = "今日任务工单总数")
    @GetMapping("/today-work-tasks-total-count")
    public Result findTodayWorkTasksTotalCount()
    {
        Integer data = workTaskService.findTodayWorkTasksTotalCount();
        return new Result(data);
    }

    @Operation(summary = "各系统设备总数及维修数量")
    @GetMapping("/device-count-by-system")
    public Result findDeviceCountBySystem()
    {
        List<Object> data = new ArrayList<>();
        List<NameValue> systemDeviceCount = deviceService.statSystemCount();
        List<NameValue> faultDeviceCount = faultService.statePendingCountBySystem();
        Map<String, Object> faultDeviceMap = faultDeviceCount.stream().collect(Collectors.toMap(NameValue::getName, NameValue::getValue));
        for (NameValue nv : systemDeviceCount)
        {
            Map<String, Object> item = new LinkedHashMap<>();
            item.put("system", nv.getName());
            item.put("total", nv.getValue());
            Object fault = faultDeviceMap.get(nv.getName());
            item.put("fault", fault == null ? 0 : fault);
            data.add(item);
        }
        return new Result(data, data.size());
    }

    @Operation(summary = "人员运维工作量统计")
    @GetMapping("/user-workload")
    public Result findUserWorkload(Integer limit)
    {
        if (limit == null)
        {
            limit = 10;
        }
        List<Map<String, Object>> data = userService.statUserWorkload(limit);
        return new Result(data, data.size());
    }

    @Operation(summary = "按天统计日常巡检")
    @GetMapping("/daily-patrols")
    public Result statDailyPatrols(Integer days)
    {
        if (days == null)
        {
            days = 30;
        }
        List<NameValue> data = patrolService.statDailyPatrols(days);
        return new Result(data, data.size());
    }

    @Operation(summary = "按天统计缺陷上报")
    @GetMapping("/daily-faults")
    public Result statDailyFaults(Integer days)
    {
        if (days == null)
        {
            days = 30;
        }
        List<NameValue> data = faultService.statDailyFaults(days);
        return new Result(data, data.size());
    }

    @Operation(summary = "按天统计缺陷维修")
    @GetMapping("/daily-repairs")
    public Result statDailyRepairs(Integer days)
    {
        if (days == null)
        {
            days = 30;
        }
        List<NameValue> data = repairService.statDailyRepairs(days);
        return new Result(data, data.size());
    }

    @Operation(summary = "按天统计任务工单")
    @GetMapping("/daily-work-tasks")
    public Result statDailyWorkTasks(Integer days)
    {
        if (days == null)
        {
            days = 30;
        }
        List<NameValue> data = workTaskService.statDailyWorkTasks(days);
        return new Result(data, data.size());
    }

    @Operation(summary = "按天统计专项保养")
    @GetMapping("/daily-maintain-tasks")
    public Result statDailyMaintainTasks(Integer days)
    {
        if (days == null)
        {
            days = 30;
        }
        List<NameValue> data = maintainTaskService.statDailyMaintainTasks(days);
        return new Result(data, data.size());
    }

    @Operation(summary = "按天统计运维工单数")
    @GetMapping("/daily-work-orders")
    public Result statDailyWorkOrders(Integer days)
    {
        if (days == null)
        {
            days = 30;
        }
        List<NameValue> data = userService.statDailyWorkOrders(days);
        return new Result(data, data.size());
    }

}
